@using BTCPayServer.Forms
@using Microsoft.AspNetCore.Mvc.TagHelpers
@inject BTCPayServer.Security.ContentSecurityPolicies Csp
@model BTCPayServer.Forms.ModifyForm
@{
    Csp.UnsafeEval();
    var storeId = Context.GetCurrentStoreId();
    var formId = Context.GetRouteValue("id");
    var isNew = formId is null;
    ViewData.SetActivePage(StoreNavPages.Forms, isNew ? StringLocalizer["Create Form"] : StringLocalizer["Edit Form"], Model.Name);
}

@section PageHeadContent {
    <link href="~/main/editor.css" rel="stylesheet" asp-append-version="true" />
}

@section PageFootContent {
    <datalist id="special-field-names">
        <option text-translate="true" value="invoice_amount">Determine the generated invoice amount</option>
        <option text-translate="true" value="invoice_currency">Determine the generated invoice currency</option>
        <option text-translate="true" value="invoice_amount_adjustment">Adjusts the generated invoice amount — use as a prefix to have multiple adjustment fields</option>
        <option text-translate="true" value="invoice_amount_multiply_adjustment">Adjusts the generated invoice amount by multiplying with this value — use as a prefix to have multiple adjustment fields</option>
    </datalist>
    <template id="form-template-email">
        @FormDataService.StaticFormEmail
    </template>
    <template id="form-template-address">
        @FormDataService.StaticFormAddress
    </template>
    <template id="field-editor">
        <div class="field" v-if="field">
            <div class="form-group">
                <label for="field-editor-field-type" class="form-label" data-required text-translate="true">Type</label>
                <select id="field-editor-field-type" class="form-select" required v-model="field.type">
                    <option v-for="option in fieldTypeOptions" :key="option" :value="option" v-text="option.charAt(0).toUpperCase() + option.slice(1)"></option>
                </select>
            </div>
            <div class="form-group">
                <label for="field-editor-field-label" class="form-label" data-required text-translate="true">Label</label>
                <input id="field-editor-field-label" class="form-control" required v-model="field.label" />
            </div>
            <div class="form-group">
                <label for="field-editor-field-name" class="form-label" data-required text-translate="true">Name</label>
                <input id="field-editor-field-name" class="form-control" list="special-field-names" required v-model="field.name" />
                <div text-translate="true" class="form-text">The name of the field in the invoice's metadata.</div>
                <div text-translate="true" class="form-text text-info" v-if="field.name === 'invoice_currency'">The configured name means the value of this field will determine the invoice currency for public forms.</div>
                <div text-translate="true" class="form-text text-info" v-if="field.name === 'invoice_amount'">The configured name means the value of this field will determine the invoice amount for public forms.</div>
                <div text-translate="true" class="form-text text-info" v-if="field.name && field.name.startsWith('invoice_amount_adjustment')">The configured name means the value of this field will adjust the invoice amount for public forms and the point of sale app.</div>
                <div text-translate="true" class="form-text text-info" v-if="field.name && field.name.startsWith('invoice_amount_multiply_adjustment')">The configured name means the value of this field will adjust the invoice amount by multiplying it for public forms and the point of sale app.</div>
            </div>
            <div class="form-group" v-if="field.type === 'select'">
                <h5 class="mt-2" text-translate="true">Options</h5>
                <div class="options" v-sortable="{ handle: '.drag', onUpdate: sortOptions }">
                    <div v-for="(option, index) in field.options" :key="option.value" class="d-flex align-items-start gap-2 pt-3">
                        <button type="button" class="btn b-0 control drag">
                            <vc:icon symbol="drag" />
                        </button>
                        <div class="field flex-grow-1">
                            <label :for="`field-option-value-${index}`" class="form-label" text-translate="true">Value</label>
                            <input :id="`field-option-value-${index}`" class="form-control" v-model.lazy="option.value" />
                        </div>
                        <div class="field flex-grow-1">
                            <label :for="`field-option-text-${index}`" class="form-label" text-translate="true">Text</label>
                            <input :id="`field-option-text-${index}`" class="form-control" v-model="option.text" />
                        </div>
                        <button type="button" class="btn b-0 control remove" v-on:click="removeOption($event, index)">
                            <vc:icon symbol="remove" />
                        </button>
                    </div>
                </div>
                <button type="button" class="btn btn-link px-1 py-2 gap-1 add fw-semibold d-inline-flex align-items-center" v-on:click.stop="addOption($event)">
                    <vc:icon symbol="actions-add" />
                    <span text-translate="true">Add Option</span>
                </button>
            </div>
            <div class="form-group" v-if="field.type !== 'fieldset' && field.type !== 'mirror'">
                <label for="field-editor-field-value" class="form-label" text-translate="true">Default Value</label>
                <input id="field-editor-field-value" class="form-control" v-model="field.value" />
            </div>
            <div class="form-group" v-if="field.type === 'mirror'">
                <label for="field-editor-field-mirror" class="form-label" text-translate="true">Field to mirror</label>
                <select id="field-editor-field-mirror" class="form-select" v-model="field.value">
                    <option v-for="option in $root.allFields" v-if="option.name && option.name !== field.name" :key="option.name" :value="option.name" :selected="option.name === field.value" v-text="option.label || option.name"></option>
                </select>
                <div class="form-text" text-translate="true">The chosen field's selected value will be copied to this field upon submission.</div>
            </div>
            <div class="form-group" v-if="field.type === 'mirror'">
                <h5 class="mt-2" text-translate="true">Value Mapper</h5>
                <div class="form-text" text-translate="true">The values being mirrored from another field will be mapped to another value if configured.</div>
                <div class="options">
                    <div v-if="field.valuemap" v-for="(v, k, index) in field.valuemap" :key="k" class="d-flex align-items-start gap-2 pt-3">
                        <div class="field flex-grow-1">
                            <label :for="`field-valuemap-value-${index}`" class="form-label" text-translate="true">Original Value</label>
                            <select v-if="mirroredField && mirroredField.type === 'select'" :id="`field-valuemap-value-${index}`" class="form-select" v-on:change="updateValueMap(k, $event.target.value, v)">
                                <option v-for="option in mirroredField.options" v-if="option.text && option.value" :key="option.value" :value="option.value" :selected="k === option.value" v-text="`${option.value} (${option.text})`"></option>
                            </select>
                            <input v-else :id="`field-valuemap-value-${index}`" class="form-control" placeholder="@StringLocalizer["Value to match"]" :value="k" v-on:change="updateValueMap(k, $event.target.value, v)" />
                        </div>
                        <div class="field flex-grow-1">
                            <label :for="`field-valuemap-mapped-${index}`" class="form-label" text-translate="true">Mapped Value</label>
                            <input :id="`field-valuemap-mapped-${index}`" class="form-control" placeholder="@StringLocalizer["Value to set"]" :value="v" v-on:change="updateValueMap(k, k, $event.target.value)" />
                        </div>
                        <button type="button" class="btn b-0 control remove" v-on:click="removeValueMap($event, k)">
                            <vc:icon symbol="remove" />
                        </button>
                    </div>
                </div>
                <button type="button" class="btn btn-link px-1 py-2 gap-1 add fw-semibold d-inline-flex align-items-center" v-on:click.stop="addValueMap($event)">
                    <vc:icon symbol="actions-add" />
                    <span text-translate="true">Add mapped value</span>
                </button>
            </div>
            <div class="form-group" v-if="field.type !== 'fieldset' && field.type !== 'mirror'">
                <label for="field-editor-field-helpText" class="form-label" text-translate="true">Helper Text</label>
                <input id="field-editor-field-helpText" class="form-control" v-model="field.helpText" />
                <div class="form-text" text-translate="true">Additional text to provide an explanation for the field</div>
            </div>
            <div class="form-group form-check" v-if="field.type !== 'fieldset' && field.type !== 'mirror'">
                <input id="field-editor-field-required" type="checkbox" class="form-check-input" v-model="field.required" />
                <label for="field-editor-field-required" class="form-check-label" text-translate="true">Required Field</label>
            </div>
            <div class="form-group form-check" v-if="field.type !== 'fieldset' && field.type !== 'select' && field.type !== 'mirror'">
                <input id="field-editor-field-constant" type="checkbox" class="form-check-input" v-model="field.constant" />
                <label for="field-editor-field-constant" class="form-check-label" text-translate="true">Constant</label>
                <div class="form-text" text-translate="true">The user will not be able to change the field's value</div>
            </div>
        </div>
        <div v-else text-translate="true">Select a field to edit</div>
    </template>
    <template id="fields-editor">
        <div>
            <div class="fields list-group" :class="{ 'list-group-flush': path.length }" :data-path="path.join(',')" v-sortable="{ handle: '.drag', onUpdate (event) { const { path } = this.el.dataset; $emit('sort-fields', event, (path.indexOf(',') !== -1 ? path.split(',') : [])) } }">
                <div v-for="(field, index) in fields" :key="field.name" class="d-flex align-items-start gap-2 list-group-item" :class="{ active: field === selectedField }" v-on:click.stop="$emit('select-field', $event, path, index)">
                    <button type="button" class="btn b-0 control drag" :disabled="fields.length === 1">
                        <vc:icon symbol="actions-drag" />
                    </button>
                    <div class="field flex-grow-1">
                        <component :is="getFieldComponent(field.type)" v-bind="field" :path="path.concat(field.name)" :selected-field="selectedField" v-on="$listeners" />
                    </div>
                    <button type="button" class="btn b-0 control remove" v-on:click="$emit('remove-field', $event, path, index)">
                        <vc:icon symbol="actions-remove" />
                    </button>
                </div>
            </div>
            <button type="button" class="btn btn-link py-0 px-2 mt-2 mb-2 gap-1 add fw-semibold d-inline-flex align-items-center" v-on:click.stop="$emit('add-field', $event, path)">
                <vc:icon symbol="actions-add" />
                <span text-translate="true">Add Form Field</span>
            </button>
        </div>
    </template>
    <template id="field-type-input">
        <div class="form-check mb-0" v-if="type === 'checkbox'">
            <input class="form-check-input" :id="name" :name="name" :type="type" v-model="value" />
            <label class="form-check-label" :for="name" :data-required="required" v-sanitize="label"></label>
            <div v-if="helpText" :id="`HelpText-{name}`" class="form-text" v-sanitize="helpText"></div>
        </div>
        <div class="form-groupcheck mb-0" v-else>
            <label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
            <input class="form-control" :id="name" :name="name" :type="type" v-model="value" />
            <div v-if="helpText" :id="`HelpText-{name}`" class="form-text" v-sanitize="helpText"></div>
        </div>
    </template>
    <template id="field-type-textarea">
        <div class="form-group mb-0">
            <label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
            <textarea class="form-control" :id="name" :name="name" v-model="value"></textarea>
            <div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-sanitize="helpText"></div>
        </div>
    </template>
    <template id="field-type-select">
        <div class="form-group mb-0">
            <label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
            <select class="form-select" :id="name" :name="name">
                <option v-for="option in options" :key="option.value" :value="option.value" :selected="option.value === value" v-text="option.text"></option>
            </select>
            <div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-sanitize="helpText"></div>
        </div>
    </template>
    <template id="field-type-mirror">
        <div class="form-group mb-0">
            <label class="form-label" v-text="label" v-if="label"></label>
            <div class="form-text"><span text-translate="true">Mirror of</span> {{value}}</div>
        </div>
    </template>
    <template id="field-type-fieldset">
        <fieldset>
            <legend class="h5 mt-1 mb-2" v-text="label"></legend>
            <fields-editor :path="path" :fields="fields" :selected-field="selectedField" v-on="$listeners" class="nested-fields" />
        </fieldset>
    </template>
    <script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
    <script src="~/vendor/vue-sanitize-directive/vue-sanitize-directive.umd.min.js" asp-append-version="true"></script>
    <script src="~/vendor/vue-sortable/sortable.min.js" asp-append-version="true"></script>
    <script src="~/vendor/vue-sortable/vue-sortable.js" asp-append-version="true"></script>
    <script src="~/js/form-editor.js" asp-append-version="true"></script>
    <partial name="_ValidationScriptsPartial" />
}

<form method="post" asp-action="Modify" asp-route-id="@formId" asp-route-storeId="@storeId">
    <div class="sticky-header">
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item">
                    <a asp-controller="UIForms" asp-action="FormsList" asp-route-storeId="@storeId" text-translate="true">Forms</a>
                </li>
                <li class="breadcrumb-item active" aria-current="page">@ViewData["Title"]</li>
            </ol>
            <h2>
                @ViewData["Title"]
                <a href="https://docs.btcpayserver.org/Forms" target="_blank" rel="noreferrer noopener" title="@StringLocalizer["More information..."]">
                    <vc:icon symbol="info" />
                </a>
            </h2>
        </nav>
        <div>
            <button id="page-primary" type="submit" class="btn btn-primary order-sm-1" text-translate="true">Save</button>
            @if (!isNew)
            {
                <a class="btn btn-secondary" asp-action="ViewPublicForm" asp-route-formId="@formId" id="ViewForm" text-translate="true">View</a>
            }
        </div>
    </div>
    <partial name="_StatusMessage" />
    <div class="row mb-4">
        <div class="col-12">
            @if (!ViewContext.ModelState.IsValid)
            {
                <div asp-validation-summary="All"></div>
            }
            <div class="form-group" style="max-width: 27rem;">
                <label asp-for="Name" class="form-label" data-required></label>
                <input asp-for="Name" class="form-control" required />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="d-flex align-items-center mb-4 gap-3">
                <input asp-for="Public" type="checkbox" class="btcpay-toggle" />
                <div>
                    <label asp-for="Public"></label>
                    <div class="form-text" text-translate="true">Standalone mode, which can be used to generate invoices independent of payment requests or apps.</div>
                </div>
            </div>
        </div>
    </div>

    <div id="FormEditor" class="editor col-xxl-constrain">
        <div class="d-flex flex-wrap align-items-end justify-content-between gap-3 mb-3">
            <ul class="nav nav-pills gap-4" role="tablist">
                <li class="nav-item" role="presentation">
                    <button class="nav-link active" id="EditorTabButton" data-bs-toggle="pill" data-bs-target="#EditorTabPane" type="button" role="tab" aria-controls="EditorTabPane" aria-selected="true" text-translate="true">Editor</button>
                </li>
                <li class="nav-item" role="presentation">
                    <button class="nav-link" id="CodeTabButton" data-bs-toggle="pill" data-bs-target="#CodeTabPane" type="button" role="tab" aria-controls="CodeTabPane" aria-selected="false" text-translate="true">Code</button>
                </li>
            </ul>
            <div class="d-flex align-items-center gap-2 mb-1">
                <span class="fw-semibold" text-translate="true">Templates</span>
                <button type="button" class="btn btn-link p-0 fw-semibold" v-on:click="applyTemplate('email')" id="ApplyEmailTemplate" text-translate="true">Email</button>
                <button type="button" class="btn btn-link p-0 fw-semibold" v-on:click="applyTemplate('address')" id="ApplyAddressTemplate" text-translate="true">Address</button>
            </div>
        </div>
        <div class="tab-content">
            <div class="tab-pane fade show active" id="EditorTabPane" role="tabpanel" aria-labelledby="EditorTabButton" tabindex="0">
                <div class="row align-items-start">
                    <div class="col-12">
                        <fields-editor :path="[]"
                                       :fields="fields"
                                       :selected-field="selectedField"
                                       v-on:add-field="addField"
                                       v-on:sort-fields="sortFields"
                                       v-on:select-field="selectField"
                                       v-on:remove-field="removeField"
                                       :class="{ 'pt-2': (!fields || fields.length === 0) }"
                                       class="bg-tile pb-2 rounded" />
                    </div>
                    <div class="offcanvas offcanvas-end" tabindex="-1" ref="editorOffcanvas">
                        <div class="offcanvas-header justify-content-between p-3">
                            <h5 class="offcanvas-title" text-translate="true">Edit Field</h5>
                            <button type="button" class="btn-close" aria-label="@StringLocalizer["Close"]" v-on:click="hideOffcanvas">
                                <vc:icon symbol="close" />
                            </button>
                        </div>
                        <div class="offcanvas-body p-3">
                            <field-editor :field="selectedField" class="bg-tile w-100 rounded" />
                        </div>
                    </div>
                </div>
            </div>
            <div class="tab-pane fade" id="CodeTabPane" role="tabpanel" aria-labelledby="CodeTabButton" tabindex="0">
                <label asp-for="FormConfig" class="form-label" data-required text-translate="true">Form JSON</label>
                <textarea asp-for="FormConfig" class="form-control font-monospace" style="font-size:.85rem" rows="21" cols="21" v-model="configJSON" v-on:change="updateFromJSON"></textarea>
                <span asp-validation-for="FormConfig" class="text-danger"></span>
            </div>
        </div>
    </div>
</form>
